/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved.
 */

package pl.droidsonroids.gif;

import ohos.aafwk.ability.DataAbilityHelper;
import ohos.aafwk.ability.DataAbilityRemoteException;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.Image;
import ohos.agp.components.element.Element;
import ohos.agp.components.element.PixelMapElement;
import ohos.agp.window.service.DisplayAttributes;
import ohos.agp.window.service.DisplayManager;
import ohos.app.Context;
import ohos.global.resource.NotExistException;
import ohos.global.resource.ResourceManager;
import ohos.global.resource.WrongTypeException;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import ohos.media.image.ImageSource;
import ohos.media.image.PixelMap;
import ohos.media.image.common.ColorSpace;
import ohos.media.image.common.PixelFormat;
import ohos.media.image.common.Rect;
import ohos.media.image.common.Size;
import ohos.utils.net.Uri;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;

/**
 * 功能描述
 *
 * @author bwx484721
 * @since 2020-07-13
 */
final class GifViewUtils {
	static final List<String> SUPPORTED_RESOURCE_TYPE_NAMES = Arrays.asList("raw", "drawable", "mipmap");
	public static final int MY_MODULE = 0x00201;
	private final static HiLogLabel TAG = new HiLogLabel(HiLog.LOG_APP, MY_MODULE, GifViewUtils.class.getName());

	private GifViewUtils() {
	}

	static GifImageViewAttributes initImageView(Image view, AttrSet attrs, int defStyleAttr, int defStyleRes) throws NotExistException, WrongTypeException, IOException {
//		TODO - isInEditMode()
		if (attrs != null /*&& !view.isInEditMode()*/) {
			final GifImageViewAttributes viewAttributes = new GifImageViewAttributes(view, attrs, defStyleAttr, defStyleRes);
			final int loopCount = viewAttributes.mLoopCount;
			if (loopCount >= 0) {
				applyLoopCount(loopCount, view.getForegroundElement());
				applyLoopCount(loopCount, view.getBackgroundElement());
			}
			return viewAttributes;
		}
		return new GifImageViewAttributes();
	}

	static void applyLoopCount(final int loopCount, final Element drawable) {
		if (drawable instanceof GifDrawable) {
			((GifDrawable) drawable).setLoopCount(loopCount);
		}
	}

	static boolean setResource(Image view, boolean isSrc, int resId) throws IOException {
		ResourceManager res = view.getResourceManager();
		if (res != null) {
			try {
//				TODO - getResourceTypeName
				/*final String resourceTypeName = res.getResourceTypeName(resId);
				if (!SUPPORTED_RESOURCE_TYPE_NAMES.contains(resourceTypeName)) {
					return false;
				}*/
				GifDrawable d = new GifDrawable(view.getContext(), res, resId);
				if (isSrc) {
					view.setForeground(d);
				} else {
					view.setBackground(d);
				}
				return true;
			} catch (IOException e) {
				//ignored
			} catch (NotExistException e) {
				e.printStackTrace();
			} catch (WrongTypeException e) {
				e.printStackTrace();
			}
		}
		return false;
	}

	static boolean setGifImageUri(Image imageView, Uri uri) {
		if (uri != null) {
			try {
				imageView.setForeground(new GifDrawable(DataAbilityHelper.creator(imageView.getContext()), uri));
				return true;
			} catch (IOException | DataAbilityRemoteException ignored) {
				//ignored
			}
		}
		return false;
	}

	public static final int DENSITY_DEFAULT = 0;
	public static final int DENSITY_NONE = 65535;

	static float getDensityScale(Context context, ResourceManager res, int id) throws NotExistException, WrongTypeException, IOException {
		final int resourceDensity = res.getElement(id).getInteger();
		final int density;
		if (resourceDensity == DENSITY_DEFAULT) {
			density = DisplayAttributes.MEDIUM_DENSITY;
		} else if (resourceDensity != DENSITY_NONE) {
			density = resourceDensity;
		} else {
			density = 0;
		}
//		final int targetDensity = res.getDisplayMetrics().densityDpi;
		final int targetDensity = DisplayManager.getInstance().getDefaultDisplay(context).get().getRealAttributes().densityDpi;

		if (density > 0 && targetDensity > 0) {
			return (float) targetDensity / density;
		}
		return 1f;
	}

	static class GifViewAttributes {
		boolean freezesAnimation;
		int mLoopCount;

		/*GifViewAttributes(final View view, final AttributeSet attrs, final int defStyleAttr, final int defStyleRes) {
			final TypedArray gifViewAttributes = view.getContext().obtainStyledAttributes(attrs, R.styleable.GifView, defStyleAttr, defStyleRes);
			freezesAnimation = gifViewAttributes.getBoolean(R.styleable.GifView_freezesAnimation, false);
			mLoopCount = gifViewAttributes.getInt(R.styleable.GifView_loopCount, -1);
			gifViewAttributes.recycle();
		}*/

		GifViewAttributes(final Component view, final AttrSet attrs, final int defStyleAttr, final int defStyleRes) {
//			TODO
			/*final AttrSet gifViewAttributes = view.getContext().obtainStyledAttributes(attrs, R.styleable.GifView, defStyleAttr, defStyleRes);
//			final AttrSet gifViewAttributes = view.getContext().getResourceManager().getTheme().(attrs, R.styleable.GifView, defStyleAttr, defStyleRes);
			freezesAnimation = gifViewAttributes.getAttr(R.styleable.GifView_freezesAnimation).get().getBoolValue();
			mLoopCount = gifViewAttributes.getInt(R.styleable.GifView_loopCount, -1);
			gifViewAttributes.recycle();*/
		}

		GifViewAttributes() {
			freezesAnimation = false;
			mLoopCount = -1;
		}
	}

	static class GifImageViewAttributes extends GifViewAttributes {
		final int mSourceResId;
		final int mBackgroundResId;

		GifImageViewAttributes(final Image view, final AttrSet attrs, final int defStyleAttr, final int defStyleRes) throws NotExistException, WrongTypeException, IOException {
			super(view, attrs, defStyleAttr, defStyleRes);
			mSourceResId = getResourceId(view, attrs, true);
			mBackgroundResId = getResourceId(view, attrs, false);
		}

		GifImageViewAttributes() {
			super();
			mSourceResId = 0;
			mBackgroundResId = 0;
		}

		private static int getResourceId(Image view, AttrSet attrs, final boolean isSrc) throws NotExistException, WrongTypeException, IOException {
			final int resId = attrs.getAttr("background").get().getIntegerValue();
			if (resId > 0) {
//				TODO - getResourceTypeName
				/*final String resourceTypeName = view.getResources().getResourceTypeName(resId);    //view.getResourceManager().getTheme(resId).getThemeHash().;
				if (SUPPORTED_RESOURCE_TYPE_NAMES.contains(resourceTypeName) && !setResource(view, isSrc, resId)) {
					return resId;
				}*/
				return resId;
			}
			return 0;
		}

	}

	public static Element getElement(Context context, int resid) throws IOException, NotExistException {
		//From context get ResrouceMangager
		ResourceManager rm = context.getResourceManager();

		//Pass resrouceId and get Inputstream
		InputStream inputStream = (InputStream) rm.getResource(resid);

		//Create options to decode bimtap
		ImageSource.DecodingOptions decodingOpts = new ImageSource.DecodingOptions();
		resetOptions(decodingOpts);
		PixelMap pixelMap = decodePixelMap(inputStream, decodingOpts, "image/png");

		//create PixelMapElement using PixelMap
		return new PixelMapElement(pixelMap);
	}

	private static void resetOptions(ImageSource.DecodingOptions decodingOpts) {
		decodingOpts.desiredSize = new Size(0, 0);
		decodingOpts.desiredRegion = new Rect(0, 0, 0, 0);
		decodingOpts.desiredPixelFormat = PixelFormat.ARGB_8888;
		decodingOpts.allowPartialImage = false;
		decodingOpts.desiredColorSpace = ColorSpace.UNKNOWN;
		decodingOpts.rotateDegrees = 0.0F;
		decodingOpts.sampleSize = 1;

	}

	//decode pixelmap using inputstream and options
	public static PixelMap decodePixelMap(InputStream is, ImageSource.DecodingOptions options, String formatHint)throws IOException{
		ImageSource.SourceOptions srcOpts = new ImageSource.SourceOptions();
		srcOpts.formatHint = formatHint;
		ImageSource imageSource = ImageSource.create(is, srcOpts);
		if(null != imageSource)
			HiLog.debug(TAG, "imageSource not null");
		else
			HiLog.debug(TAG, "imageSource null");

		if (imageSource == null) {
			throw new FileNotFoundException();
		}

		return imageSource.createPixelmap(options);
	}
}
